﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Drawing;

namespace PDI
{
    public static class Histograma
    {
        public static Imagem aplicarHistograma(Imagem img)
        {


            Imagem histograma = new Imagem(new Bitmap(256, 256));

            // Histograma absoluto da imagem.
            int[] histogramaABS = new int[256];
            // Maior valor do histograma absoluto.
            int maiorValorHABS = int.MinValue;
            // Passar por todos os pixels
            for (int x = 0; x < img.getBitmap().Width; x++)
            {
                for (int y = 0; y < img.getBitmap().Height; y++)
                {
                    // Calcula o valor monocromático do pixel, considerando
                    // o método da média.
                    int media = (img.getR(x, y) + img.getG(x, y) + img.getB(x, y)) / 3;
                    // Acrescenta (1) ao histograma.
                    histogramaABS[media]++;
                    maiorValorHABS = (histogramaABS[media] > maiorValorHABS) ? histogramaABS[media] : maiorValorHABS;
                }
            }

            // Encontrar o maior valor do histograma.
            // maior - 255
            // valor - x
            double fatorProporcao = 255d / maiorValorHABS;
            // Passa pelo histograma.
            for (int i = 0; i < 256; i++)
            {
                // Calcula a altura da barrinha que deve ser desenhada.
                int altura = (int)(histogramaABS[i] * fatorProporcao);
                // Desenha a barra.
                for (int j = 0; j < altura; j++)
                {
                    histograma.setRGB(i, 255 - j, 0, 0, 0);
                }
            }

            return histograma;
        }

        public static Imagem aplicarHistogramaVertical(Imagem img)
        {
            Imagem histograma = new Imagem(new Bitmap(100, img.getBitmap().Height));

            int[] qtdeLinhas = new int[img.getBitmap().Height];

            int MaiorABS = int.MinValue;

            // correr a imagem para saber qual a maior linha
            for (int y = 0; y < img.getBitmap().Height; y++)
            {
                for (int x = 0; x < img.getBitmap().Width; x++)
                {
                    if (img.getB(x, y) > 128)
                    {
                        qtdeLinhas[y]++;
                    }
                }
                MaiorABS = qtdeLinhas[y] > MaiorABS? qtdeLinhas[y] : MaiorABS;
            }

            double fatorDeProporcao = 100d/MaiorABS;

            //for (int i = 0; i < 100; i++)
            //{
            //    for (int j = 0; j < qtdeLinhas.Length; j++)
            //    {
            //        histograma.setRGB(i, j, 0, 0, 0);
            //    }
            //}


            for (int y = 0; y < qtdeLinhas.Length; y++)
            {
                int largura = (int)(qtdeLinhas[y] * fatorDeProporcao);

                for (int x = 0; x < largura; x++)
                {
                    histograma.setRGB(x, y, 0, 0, 0);
                }
            }

            return histograma;
        }


        public static Imagem encontrar30PocentoMaiores(Imagem imagem, Imagem histograma)
        {
            Imagem imagemRetorno = imagem;
            Dictionary<int, int> valorPorLinha = new Dictionary<int, int>();

            int[] qtdeLinhas = new int[imagem.getBitmap().Height];

            int MaiorABS = int.MinValue;

            // correr a imagem para saber qual a maior linha
            for (int y = 0; y < imagem.getBitmap().Height; y++)
            {
                for (int x = 0; x < imagem.getBitmap().Width; x++)
                {
                    if (imagem.getB(x, y) > 128)
                    {
                        qtdeLinhas[y]++;
                    }
                } 
                valorPorLinha.Add(y, qtdeLinhas[y]);
            }

            List<int> listaOrdenanos = new List<int>();

            foreach(KeyValuePair<int,int> valor in valorPorLinha.OrderBy(valor => valor.Value))
            {
                listaOrdenanos.Add(valor.Key);
            }

            int qtdeLinhasDescartadas = (int)(histograma.getBitmap().Height /5d * 4);

            for (int i = 0; i < qtdeLinhasDescartadas; i++)
            {
                for (int j = 0; j < imagemRetorno.getBitmap().Width; j++)
                {
                    imagemRetorno.setRGB(j, listaOrdenanos[i], 255, 255, 255);
                }
            }

            return imagemRetorno;

        }
    }
}
